# -*- coding: utf-8 -*-
import json
import random
import mod.client.extraClientApi as clientApi
from mod.client.ui.controls.baseUIControl import BaseUIControl
from legendaryPowerClientScript.ui.base.baseComponent import BaseComponent, AlphaChangeTween, SizeChangeTween, PosChangeTween, ColorChangeTween, StasisTween
from legendaryPowerClientScript.ui.base.buttonComponent import ButtonComponent
from legendaryPowerClientScript.ui.base.imageComponent import ImageComponent
from legendaryPowerClientScript.ui.base.itemComponent import ItemComponent
from legendaryPowerClientScript.ui.base.itemRendererComponent import ItemRendererComponent
from legendaryPowerClientScript.ui.base.labelComponent import LabelComponent
from legendaryPowerClientScript.ui.base.listComponent import ListComponent
from legendaryPowerClientScript.ui.base.progressBarComponent import ProgressBarComponent
from legendaryPowerClientScript.ui.base.selectAmountComponent import SelectAmountComponent
from legendaryPowerClientScript.ui.base.sliderBarComponent import SliderComponent
from legendaryPowerClientScript.ui.base.textboxComponent import TextboxComponent
from legendaryPowerClientScript.ui.base.toggleComponent import ToggleComponent
from legendaryPowerClientScript.util import apiUtil, vector
from mod.client.ui.screenNode import ScreenNode
class UIBase(ScreenNode):
    """
    UIBase类继承自ScreenNode，表示界面基类。
    在创建UI时，您可以直接让该UI继承此类，并且像操纵网易原生UI一样操作此类（甚至将已有的继承ScreenNode的直接改成继承UIBase也是可以的）
    在网易版之上，您可以用 getButton 等函数直接获取按钮（比网易的高效），并添加UI动画
    一些常用的组合控件，如按钮、开关、列表 都有封装，创建列表只需要一行 getList ，增删元素也只需要 SetElementSize() 就行
    若需要打开UI，请调用 apiUtil.OpenGui(ui)， 关闭则使用 apiUtil.CloseGui(ui)。
    系统会根据用户平台，自动选择PushScreen模式（PC，支持悬浮控件）或是 SetScreenVisible 模式（无需重复初始化UI）打开

    属性：
        - ui: UI对象
        - isPush: 是否为推入式界面
        - canOverrideByOtherGui: 是否可以被其他界面覆盖
        - name: 名称
        - components: 组件字典
        - update: 是否更新
        - displaying: 是否显示中
        - textBoxes: 文本框列表
        - _updateTextBoxesTaskId: 更新文本框任务ID
        - taskId: 任务ID
        - inactive: 不活动组件列表
        - shouldGause: 是否应该暂停
        - activeComponents: 活动组件列表
        - tweening: 动画列表
        - mode: 模式
        - sfxs: 特效
        - canCloseByEsc: 是否可以按“Esc”键关闭
        - closing: 是否正在关闭
        - _hovering: 当前悬停的组件
        - createCb: 创建回调函数
        - _hoveringItem: 当前悬停的物品
        - _initedShared: 是否已初始化共享
        - _useCallback: 使用回调函数
        - _sellCallback: 出售回调函数
        - _componentTypeCache: 组件类型缓存
        - __showingItem: 显示的物品
    """

    def HandleEventUI(self, data):
        # type: () -> None
        """
        接收到事件后，会将data缓存起来，并开始构建界面
        界面展示后，会自动触发事件 _onRecievedEvent
        若此UI是收到事件就打开的类型，则可以直接在ui的__init__中调用：

        RegisterEventServerUI(事件名", self, self.HandleEventUI)

        然后重写onRecievedEvent，在其中根据服务端发来的包构建UI
        """
        pass

    def onRecievedEvent(self, data):
        # type: () -> None
        """
        见HandleEventUI
        """
        pass

    def setHoveringItem(self, item):
        # type: (itemDict or None) -> None
        """
        （PC）设置鼠标正在悬浮的物品。弹出的物品描述框会随着鼠标一起移动

        Args:
            item (itemDict or None): 悬浮的物品。注意客户端是没有LegendaryItem类的，所以请用itemDict
        """
        pass

    def getRandom(self, range):
        # type: () -> None
        """
        生成0~range间的随机数
        """
        pass

    def setHovering(self, component):
        # type: (BaseComponent) -> None
        """
        （PC）将该控件标为鼠标正在悬浮的控件

        Args:
            component (BaseComponent): 鼠标正在悬浮的控件
        """
        pass

    def SetDisplay(self, display):
        # type: () -> None
        """
        废弃，若需要打开UI，请调用 apiUtil.OpenGui(ui)， 关闭则使用 apiUtil.CloseGui(ui)。
        """
        pass

    def setUpdate(self):
        # type: () -> None
        """
        刷新UI，随便复数次调用都行
        """
        pass

    def SetScreenVisible(self, visible):
        # type: () -> None
        """
        废弃，若需要打开UI，请调用 apiUtil.OpenGui(ui)， 关闭则使用 apiUtil.CloseGui(ui)。
        """
        pass

    def SetText(self, path, text):
        # type: () -> None
        """
        废弃，请用 getLabel().SetText()
        """
        pass

    def SetAlpha(self, path, alpha):
        # type: () -> None
        """
        废弃，请用 getImage().SetAlpha()
        """
        pass

    def SetTouchEnable(self, path, visible):
        # type: () -> None
        """
        废弃，请用 getButton().SetTouchEnable()
        """
        pass

    def SetVisible(self, path, visible, sync=False):
        # type: () -> None
        """
        废弃，请用 getComponent().SetVisible()
        """
        pass

    def SetSpriteBright(self, path, bright):
        # type: () -> None
        """
        废弃，请用 getImage().SetSpriteBright()
        """
        pass

    def SetSpriteUVSize(self, path, gray):
        # type: () -> None
        """
        废弃，请用 getImage().SetSpriteUVSize()
        """
        pass

    def SetSpriteUV(self, path, gray):
        # type: () -> None
        """
        废弃，请用 getImage().SetSpriteUV()
        """
        pass

    def SetSprite(self, path, gray):
        # type: () -> None
        """
        废弃，请用 getImage().SetSprite()
        """
        pass

    def SetSpriteGray(self, path, gray):
        # type: () -> None
        """
        废弃，请用 getImage().SetSpriteGray()
        """
        pass

    def SetUiItem(self, path, name, aux, enchanted=False):
        # type: () -> None
        """
        废弃，请用 getItemRenderer().SetUiItem()
        """
        pass

    def AddTouchEventHandler(self, path, cb, data=None):
        # type: () -> None
        """
        废弃，请用 getButton().SetTouchUp()
        """
        pass

    def PopScreen(self):
        # type: () -> None
        """
        废弃，若需要打开UI，请调用 apiUtil.OpenGui(ui)， 关闭则使用 apiUtil.CloseGui(ui)。
        """
        pass

    def getImage(self, path):
        # type: (str) -> ImageComponent
        """
        获取ImageComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。

        Returns:
            ImageComponent: 图像组件对象。
        """
        pass

    def getItemRenderer(self, path):
        # type: (str) -> ItemRendererComponent
        """
        获取ItemRendererComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。

        Returns:
            ItemRendererComponent: 选项渲染组件对象。
        """
        pass

    def getButton(self, path):
        # type: (str) -> ButtonComponent
        """
        获取ButtonComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。

        Returns:
            ButtonComponent: 按钮组件对象。
        """
        pass

    def getPanel(self, path):
        # type: (str) -> BaseComponent
        """
        获取BaseComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。

        Returns:
            BaseComponent: 基础组件对象。
        """
        pass

    def getLabel(self, path):
        # type: (str) -> LabelComponent
        """
        获取LabelComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。

        Returns:
            LabelComponent: 标签组件对象。
        """
        pass

    def getSelectAmount(self, path):
        # type: (str) -> SelectAmountComponent
        """
        获取SelectAmountComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。

        Returns:
            SelectAmountComponent: 数量选择组件对象。
        """
        pass

    def getToggle(self, path):
        # type: (str) -> ToggleComponent
        """
        获取ToggleComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。

        Returns:
            ToggleComponent: 切换组件对象。
        """
        pass

    def getList(self, path, param=None):
        # type: (str) -> ListComponent
        """
        获取ListComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。
            param: 参数。

        Returns:
            ListComponent: 列表组件对象。
        """
        pass

    def getItem(self, path, param=None):
        # type: (str) -> ItemComponent
        """
        获取ItemComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。
            param: 参数。

        Returns:
            ItemComponent: 选项组件对象。
        """
        pass

    def getTextbox(self, path, param=None):
        # type: (str) -> TextboxComponent
        """
        获取TextboxComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。
            param: 参数。

        Returns:
            TextboxComponent: 文本框组件对象。
        """
        pass

    def getSlider(self, path, param=None):
        # type: (str) -> SliderComponent
        """
        获取SliderComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。
            param: 参数。

        Returns:
            SliderComponent: 滑杆组件对象。
        """
        pass

    def getProgressbar(self, path, param=None):
        # type: (str) -> ProgressBarComponent
        """
        获取ProgressBarComponent对象。

        Args:
            path: 从UI根目录出发的组件路径。
            param: 参数。

        Returns:
            ProgressBarComponent: 进度条组件对象。
        """
        pass

    def registerTextBox(self, textBox):
        # type: () -> None
        """
        注册文本框组件对象。

        Args:
            textBox: 文本框组件对象。
        """
        pass

    def ChangeNotify(self, item):
        # type: (dict) -> None
        """
        在屏幕右侧弹出新获得物品的通知信息

        Args:
            item (dict): 需要显示的物品信息

        Returns:
            None
        """
        pass

    def onDisplay(self):
        # type: () -> None
        """
        重写此函数即可在每次打开界面时执行相关逻辑
        Returns:
            None
        """
        pass

    def canEdit(self):
        # type: () -> bool
        """
        判断此时是否可以进行编辑操作（PC：界面显示时，PE：随时都可以）

        Returns:
            bool: 是否可以编辑
        """
        return False


    def Create(self):
        # type: () -> None
        """
        重写此函数即可在创建界面时执行相关逻辑（PC：每次打开都会触发，PE：首次打开界面时触发）
        Returns:
            None
        """
        pass

    def TurnOff(self):
        # type: () -> None
        """
        重写此函数即可在关闭界面前执行相关逻辑

        Returns:
            None
        """
        pass

    def ChangeHeader(self, message):
        # type: (str) -> None
        """
        添加一条抬头显示的信息

        Args:
            message (str): 需要显示的消息内容

        Returns:
            None
        """
        pass

    def OpenLore(self, lore, x, y, useCallback=None, useButtonText="确定"):
        # type: (list[str]) -> None
        """
        在指定的x，y位置（一般是在触摸事件中的 TouchPosX TouchPosY 值）弹出文字悬浮界面。

        Args:
            lore (list[str]): 需要显示的文字信息
            x (int) 左上角的X坐标 一般是在触摸事件中的 TouchPosX
            y (int) 左上角的Y坐标 一般是在触摸事件中的 TouchPosY
            useCallback (callable) 玩家点击按钮时执行的回调 默认None
            useButtonText (str) 按钮的显示名字，默认 确定

        Returns:
            None
        """
        pass

    def HideLores(self, args=None):
        # type: () -> None
        """
        隐藏所有悬浮描述，包括物品描述和文字描述
        """
        pass

    def OpenItemLore(self, item, x, y, useCallback=None, sellCallback=None, useName="使用", sellName="售出"):
        # type: (itemDict) -> None
        """
        在指定的x，y位置（一般是在触摸事件中的 TouchPosX TouchPosY 值）弹出文字悬浮界面。

        Args:
            lore (itemDict): 需要显示的物品信息
            x (int) 左上角的X坐标 一般是在触摸事件中的 TouchPosX
            y (int) 左上角的Y坐标 一般是在触摸事件中的 TouchPosY
            useCallback (callable) 玩家点击左侧按钮时执行的回调 默认None
            sellCallback (callable) 玩家点击右侧按钮时执行的回调 默认None
            useButtonText (str) 左侧按钮的显示名字，默认 确定
            sellName (str) 右侧按钮的显示名字，默认 售出

        Returns:
            None
        """
        pass

    def InitItemFly(self, fromPosition, toPosition, item1, item2):
        # type: (tuple[int, int], tuple[int, int]) -> None
        """
        让两个物品出现在各自的位置，并飞往彼此的位置

        Args:
            fromPosition (tuple[int, int]): 物品1的起始位置
            toPosition (tuple[int, int]): 物品2的起始位置
            item1 (itemDict) 物品1的信息
            item2 (itemDict) 物品2的信息

        Returns:
            None
        """
        pass

